package com.opcode.costatablet.ui.dashboard;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;

import com.opcode.costatablet.R;
import com.opcode.costatablet.ui.dashboard.leftmenu.KitchenLeftMenuActivity;
import com.opcode.costatablet.ui.dialogs.RoundedProgressDialogBase;
import com.opcode.nebulamobil.base.activities.FragmentActivityBase;
import com.opcode.nebulamobil.base.components.LinearLayoutBase;
import com.opcode.nebulamobil.base.components.ListViewBase;
import com.opcode.nebulamobil.base.components.TextViewBase;
import com.opcode.nebulamobil.base.fragments.ResponsiveFragmentBase;
import com.opcode.nebulamobil.base.interfaces.ConnectionListener;
import com.opcode.nebulamobil.base.interfaces.OnListViewBaseItemClickListener;
import com.opcode.nebulamobil.information.ApplicationInfo;
import com.opcode.nebulamobil.information.dataforms.costadataforms.ConnectionStatus;
import com.opcode.nebulamobil.information.dataforms.costadataforms.ConnectionStatus.ConnectionStatusInfo;
import com.opcode.nebulamobil.information.dataforms.costadataforms.OrderDataForm;
import com.opcode.nebulamobil.information.dataforms.costadataforms.PersonalDataForm;
import com.opcode.nebulamobil.information.requests.costarequests.OrderListUpdateReq;
import com.opcode.nebulamobil.information.requests.costarequests.OrderPrepareReq;
import com.opcode.nebulamobil.information.responses.JSONResponse;
import com.opcode.nebulamobil.information.responses.costaresponses.ActivationResp;
import com.opcode.nebulamobil.information.responses.costaresponses.OrderListUpdateResp;
import com.opcode.nebulamobil.information.responses.costaresponses.PersonalListResp;
import com.opcode.nebulamobil.utility.JsonConverter;
import com.opcode.nebulamobil.utility.STSFileManager;
import com.opcode.nebulamobil.utility.STSLog;
import com.opcode.nebulamobil.utility.UniqueIdCreator;


/**
 * Bu sınıf,mutfakta kullanılacak olan tablet uygulamasının anba ekranını oluşturur.
 * Bu uygulamada başka ekran kullanılmayacaktır. 
 * 
 * @author Okan ERDOĞAN
 *
 * 30 Haz 2014
 */
public class KitchenFragment extends ResponsiveFragmentBase implements ConnectionListener{

	//Referanslar
	private View vi;
	private ListViewBase orderedFoodListview;
	private OrderedFoodListAfterAdapter orderedFoodListAdapter;
	private ArrayList<OrderDataForm> orderedFoodList;
	private Handler myHandler=null;
	private Runnable myRunnable=null,myRunnable2=null;
	private MediaPlayer m;
	private TextViewBase kitchenNameTextView,noOrderMessageTextview;
	private ActivationResp activationResp;
	private RoundedProgressDialogBase roundedProgressDialogBase;

	/*
	 *  Bu değişken sistemde tanımlı bütün personel listesini tutmaktadır.
	 *  Böylece seçili personele mesaj gönderilebilir.
	*/
	private ArrayList<PersonalDataForm> personalDataFormList;

	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
		
		this.roundedProgressDialogBase=new RoundedProgressDialogBase();
		
		/**
		 * Dosya işlemleri yapabilmek için gerekli nesne oluşturuluyor.
		 */
		STSFileManager.createFileOperator(Environment.getExternalStorageDirectory()+"//settings.txt");

		this.vi = inflater.inflate(R.layout.kitchen_fragment_layout, container,false);
		this.orderedFoodListview=(ListViewBase) this.vi.findViewById(R.id.ordered_food_listview);
		this.kitchenNameTextView=(TextViewBase) this.vi.findViewById(R.id.kitchen_name_textview);
		
		
		this.noOrderMessageTextview=(TextViewBase) this.vi.findViewById(R.id.no_order_message_textview);
		
		
		OrderListUpdateResp orderListUpdateResp=(OrderListUpdateResp) this.getActivity().getIntent().getSerializableExtra("OrderListUpdateResp");
		
		String deviceName=(String) this.getActivity().getIntent().getSerializableExtra("DeviceName");
		kitchenNameTextView.setText(deviceName);

		if(orderListUpdateResp.getOrderList()!=null){
			this.orderedFoodList=orderListUpdateResp.getOrderList();
		}else{
			/*
			 * Bu bölümde yer alan kod parçaları demo amaçlı yazılmıştır.
			 * Gerçek uygulamada buradaki bilgiler sunucudan gelecektir.
			 */
			this.orderedFoodList=new ArrayList<OrderDataForm>();
		}
		
		
		
		/*
		 * Bu bölümde de listview'a elemanları yerleştirmek için gerekli adapter nesnesi oluşturuluyor ve listview'a parametre olarak veriliyor.
		 */
		this.orderedFoodListAdapter=new OrderedFoodListAfterAdapter(getActivity(), R.layout.kitchen_ordered_list,orderedFoodList );
		this.orderedFoodListview.setAdapter(orderedFoodListAdapter);
		
		
		/**
		 * 
		 */
		myHandler = new Handler();	
		myRunnable = new Runnable() {
			public void run() {
				orderedFoodListAdapter=new OrderedFoodListAfterAdapter(getActivity(), R.layout.kitchen_ordered_list,orderedFoodList );
				orderedFoodListview.setAdapter(orderedFoodListAdapter);
			}
		};
		
		myRunnable2 = new Runnable() {
			public void run() {
				kitchenNameTextView.setText(activationResp.getDeviceName());
			}
		};

		m=new MediaPlayer();

		orderedFoodListview.setOnListViewBaseItemClickListener(new OnListViewBaseItemClickListener() {
			
			@Override
			public void onListViewItemClick(AdapterView<?> parent, View view,int position, long id) {
				
			}
		});

		
		orderedFoodListview.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {	

				createOrderPrepareRequest(orderedFoodList.get(position).getOrderId());

				orderedFoodList.remove(position);
				orderedFoodListAdapter=new OrderedFoodListAfterAdapter(getActivity(), R.layout.kitchen_ordered_list,orderedFoodList );
				orderedFoodListview.setAdapter(orderedFoodListAdapter);

				((KitchenLeftMenuActivity)getActivity()).playSoundFromAsset("delete.wav");

				return false;
			}
		});
		
		return this.vi;
	}
	
	public void onStart(){
		super.onStart();
		
		/**
		 * Aktivite sunucudan gelecek olan responseları dinleyebilmek için ayarlama yapılıyor.
		 */
		ApplicationInfo.setResponseListener(this);

		/**
		 * Aktivite service'ten bağlantı ile ilgili bildirimleri almak isteyecektir.
		 * işte bu bildirimleri alabilmek için connectionListener özelliği veriliyor.
		 */
		ApplicationInfo.setConnectionListener(this);
		

	}
	
	
	public void onResume(){
		super.onResume();
		
		((KitchenLeftMenuActivity)getActivity()).createPersonalRequest();
		
	}
	
	
	/**
	 * Bu sınıf listview'a parametre olarak verilen ve listview için gerekli elemanların yerleştirilmesini sağlayan adapter nesnesine aittir.
	 * @author Okan ERDOĞAN
	 *
	 * 30 Haz 2014
	 */
	class OrderedFoodListAfterAdapter extends ArrayAdapter<OrderDataForm>{

		private Context context;
		private int resourceId;
		private ArrayList<OrderDataForm> arrayList;
		TextViewBase active_table_item_textview;
		
		public OrderedFoodListAfterAdapter(Context context, int textViewResourceId,ArrayList<OrderDataForm> objects) {
			super(context, textViewResourceId, objects);
			
			this.context = context;
			this.resourceId = textViewResourceId;
			
			this.arrayList = objects;
			
			if(this.arrayList.size()>0){
				orderedFoodListview.setVisibility(View.VISIBLE);
				noOrderMessageTextview.setVisibility(View.GONE);
			}else{
				orderedFoodListview.setVisibility(View.GONE);
				noOrderMessageTextview.setVisibility(View.VISIBLE);
			}
			
		}	
		
		/**
		 * Listview'a set edilecek her bir eleman için bu metod bir defa otomatik olarak çağrılır.
		 */
		public View getView(int position, View convertView, ViewGroup parent) {
			
				/*
				 * ConvertView referansı listview'daki o an için set edilen elemanı ifade eder.
				 */
				convertView = LayoutInflater.from(this.context).inflate(this.resourceId, null);
		        
				/*
				 * kitchenFoodListLinearlayout nesne referansı da o an için set edilen liste elemanında yer alan linearlayout objesine referanslık eder.
				 * Bu nesne referansı aşağıdaki for döngüsü içerisinde sipariş edilen her bir yemek için linearlayout'a bir view eklemek için kullanılacaktır.
				 */
		        LinearLayoutBase kitchenFoodListLinearlayout=(LinearLayoutBase) convertView.findViewById(R.id.kitchen_food_list_linearlayout);		        
		        
		       
	        	active_table_item_textview=(TextViewBase) convertView.findViewById(R.id.active_table_item_textview);
	        	
	        	
	        	if(this.arrayList.get(position)!=null){
		        	active_table_item_textview.setText("Masa:"+this.arrayList.get(position).getTableNumber());
	        	}
	        	
	        	 
	        	if(this.arrayList.get(position).getOrderedFoodList()!=null){
	        		
	        		TreeMap<String, Integer> orderedFoodList=this.arrayList.get(position).getOrderedFoodList();
		        	Set<Entry<String, Integer>> entry=orderedFoodList.entrySet();
		        	Iterator<Entry<String, Integer>> itr=entry.iterator();
		        	
		        	while(itr.hasNext()){
		        		Entry<String, Integer> nextEntry=itr.next();
		        		String foodName=nextEntry.getKey();
		        		Integer foodCount=nextEntry.getValue();
		        		
		        		View vi=LayoutInflater.from(this.context).inflate(R.layout.food_after_selection_item,null);
			        	TextViewBase selected_food_name=(TextViewBase) vi.findViewById(R.id.selected_food_name);		    
			        	TextViewBase selected_food_count=(TextViewBase) vi.findViewById(R.id.selected_food_count);

			        	selected_food_name.setText(foodName);
			        	
			        	selected_food_count.setText(""+foodCount);
			        	kitchenFoodListLinearlayout.addView(vi,0);
		        	}
	        		
	        		/*
			         * Bu döngü bir sipariş nesnesinin içerisinde sipariş edilen her bir yemek için bir kere döner.
			         */
			        for(int i=0;i<this.arrayList.get(position).getOrderedFoodList().size();i++){
			        	/*
			        	 * Her bir sipariş objesinin içerisinde yer alan her bir yemek için bir view nesnesi oluşturulur.
			        	 * Daha sonra da bu view'dan ilgili elemanlar elde edilerek gerekli ayarlamalar yapılır.
			        	 */
			        	
					}	
	        	}		 
	        	
			return convertView;
		}
		
		
		public void notifyDataSetChanged(){
			super.notifyDataSetChanged();
			this.arrayList=orderedFoodList;	
		}
	}

	public void createRequest(){
		OrderListUpdateReq orderListUpdateReq=new OrderListUpdateReq();
		orderListUpdateReq.setType("OrderListUpdateReq");
		orderListUpdateReq.setRequestId(UniqueIdCreator.createUniqueID());
		ApplicationInfo.getRequestListener().jsonRequestCame(JsonConverter.toJsonString(orderListUpdateReq));
	}
	
	
	public void createOrderPrepareRequest(long orderId){
		OrderPrepareReq orderPrepareReq=new OrderPrepareReq();
		orderPrepareReq.setType("OrderPrepareReq");
		orderPrepareReq.setRequestId(UniqueIdCreator.createUniqueID());
		orderPrepareReq.setPreparedOrderId(orderId);
		ApplicationInfo.getRequestListener().jsonRequestCame(JsonConverter.toJsonString(orderPrepareReq));
	}

	/*
	 * Sunucuyla olan bağlantıda herhangi bir durum değişikliği meydana geldiğinde bu metod ConnectionService tarafından tetiklenir.
	 */
	@Override
	public void connectionStatusChanged(ConnectionStatus status) {
		System.out.println(status.getConnectionInfoMessage());
		System.out.println(status.getConnectionStatusInfo());
		
		if(status.getConnectionStatusInfo().equals(ConnectionStatusInfo.CONNECTED)){		
			Log.i("KitchenFragment", "Bağlantı kuruldu.");

		}else if(status.getConnectionStatusInfo().equals(ConnectionStatusInfo.CONNECTION_LOST)||status.getConnectionStatusInfo().equals(ConnectionStatusInfo.SERVER_NOT_FOUND)){
			
		}
	}


	
	@Override
	public void responseCame(String response) {
		Log.i("KitchenFragment",response );
		
		JSONResponse responseObject=(JSONResponse) JsonConverter.fromJsonString(response, JSONResponse.class);

		if(responseObject.getType().equals("ActivationResp")){
			this.activationResp=(ActivationResp) JsonConverter.fromJsonString(response, ActivationResp.class);
			if(activationResp.isActResult()){
				Log.i("SplashFragment", "Aktivasyon onaylandı.Personel listesi alınıyor.");

				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					STSLog.writeLog(e,this.getClass().getCanonicalName(),"Thread 1sn uykuya gönderilirken hata alındı.");														
				}
				myHandler.post(myRunnable2);
				createRequest();
			}else{
				Log.i("SplashFragment", activationResp.getActMessage());
			}
		}else if(responseObject.getType().equals("OrderListUpdateResp")){
			((FragmentActivityBase)this.getActivity()).showGeneralDialog(roundedProgressDialogBase, "KITCHEN_FRAGMENT_PROGRESS_DIALOG");

			OrderListUpdateResp orderListUpdateResp=(OrderListUpdateResp) JsonConverter.fromJsonString(response, OrderListUpdateResp.class);		
			orderedFoodList=orderListUpdateResp.getOrderList();
			myHandler.post(myRunnable);
			((KitchenLeftMenuActivity)getActivity()).playSoundFromAsset("accept.wav");
			((FragmentActivityBase)getActivity()).closeGeneralDialog(roundedProgressDialogBase, "KITCHEN_FRAGMENT_PROGRESS_DIALOG");
				

		}else if(responseObject.getType().equals("PersonalListResp")){
			PersonalListResp personalListResp=(PersonalListResp) JsonConverter.fromJsonString(response, PersonalListResp.class);
			if(personalListResp.getPersonalList()!=null){
				
				/*
				 * Sunucudan gelen personelListesi bilgisi sharedPreferences'a yazılıyor.
				 */
				((FragmentActivityBase)getActivity()).createSharedPreferencesManager("sharedpreferences",this.getActivity());
				((FragmentActivityBase)getActivity()).writeToSharedPreferences("personalDataFormList", JsonConverter.toJsonString(personalListResp));
				
				this.personalDataFormList=personalListResp.getPersonalList();
				((KitchenLeftMenuActivity)getActivity()).updateGUI(personalDataFormList);
				((FragmentActivityBase)getActivity()).closeGeneralDialog(KitchenLeftMenuActivity.roundedProgressDialogBase, "KITCHEN_FRAGMENT_PROGRESS_DIALOG");

			}
		}
		

	}
}
